package com.dq.health.utils.data;

import java.io.Serializable;
import java.util.HashSet;
import java.util.LinkedHashSet;

/**
 * 树节点
 * 
 * @author *
 * @param <T>
 */
public class Node<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    private String nodeId;
    private String nodeName;
    private Boolean isLeaf = true;
    private Boolean isAddChild = true;
    private Boolean isMatch = false;

    /**
     * 节点内容
     */
    private T data;

    /**
     * 父节点编号
     */
    private HashSet<String> parentNodeIds;

    /**
     * 子节点列表
     */
    private LinkedHashSet<Node<T>> children = new LinkedHashSet<>();

    /**
     * 构造函数
     * 
     */
    public Node(String nodeId, HashSet<String> parentNodeIds) {
        super();
        this.nodeId = nodeId;
        this.parentNodeIds = parentNodeIds;
    }

    public Node() {
        super();
    }

    public boolean isRootNode() {
        if (parentNodeIds == null) {
            return false;
        }

        if (parentNodeIds.size() != 1) {
            return false;
        }

        if (parentNodeIds.contains(TreeUtil.ROOT_NODE_ID)) {
            return true;
        }

        return false;
    }

    public Boolean getIsMatch() {
        return isMatch;
    }

    public void setIsMatch(Boolean isMatch) {
        this.isMatch = isMatch;
    }

    public Boolean getIsAddChild() {
        return isAddChild;
    }

    public void setIsAddChild(Boolean isAddChild) {
        this.isAddChild = isAddChild;
    }

    public HashSet<String> getParentNodeIds() {
        return parentNodeIds;
    }

    public void setParentNodeIds(HashSet<String> parentNodeIds) {
        this.parentNodeIds = parentNodeIds;
    }

    public String getNodeId() {
        return nodeId;
    }

    public void setNodeId(String nodeId) {
        this.nodeId = nodeId;
    }

    public String getNodeName() {
        return nodeName;
    }

    public void setNodeName(String nodeName) {
        this.nodeName = nodeName;
    }

    public Boolean getIsLeaf() {
        return isLeaf;
    }

    public void setIsLeaf(Boolean isLeaf) {
        this.isLeaf = isLeaf;
    }

    /**
     * get &set
     * 
     * @return
     */
    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public LinkedHashSet<Node<T>> getChildren() {
        return children;
    }

    public void setChildren(LinkedHashSet<Node<T>> children) {
        this.children = children;
    }

    public void addChildNodes(LinkedHashSet<Node<T>> childNodes) {
        if (childNodes == null || childNodes.size() == 0) {
            return;
        }

        for (Node<T> node : childNodes) {
            HashSet<String> parentNodeIds2 = node.getParentNodeIds();
            if (parentNodeIds2 == null || parentNodeIds2.size() == 0) {
                node.setParentNodeIds(SetUtil.toSet(this.getNodeId()));
            }
        }

        getChildren().addAll(childNodes);
        setIsLeaf(false);
    }

    public void addChildNode(Node<T> childNode) {
        HashSet<String> parentNodeIds2 = childNode.getParentNodeIds();
        if (parentNodeIds2 == null || parentNodeIds2.size() == 0) {
            childNode.setParentNodeIds(SetUtil.toSet(this.getNodeId()));
        }

        getChildren().add(childNode);
        setIsLeaf(false);
    }

    public void removeChildNode() {
        getChildren().clear();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((nodeId == null) ? 0 : nodeId.hashCode());
        return result;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Node other = (Node)obj;
        if (nodeId == null) {
            if (other.nodeId != null) {
                return false;
            }
        } else if (!nodeId.equals(other.nodeId)) {
            return false;
        }
        return true;
    }

}
